﻿using UnityEngine;
using System;
using System.Collections;
using System.Linq;
using Newtonsoft.Json;

namespace Zhongy
{
    /// <summary>
    /// 本类为网络消息发送管理中心
    /// 1、Game端UDP广播（广播游戏状态）
    /// 2、Game端TCP发送或回应client端消息
    /// </summary>
    public class NetSManager: MananerBase
    {
        public static NetSManager Instance = null;

        private ServerPer server;
        private BroadcastPer broader;

        private static MsgRecord msgRecord = Record.MsgRecord;
        void Awake()
        {
            Instance = GetComponent<NetSManager>();

            Application.runInBackground = true;

            Loom.QueueOnMainThread(() => { });

            Bind(new int[5]
            {
                GameEvtCode.GameDisconnect,
                GameEvtCode.GameConnect,
                GameEvtCode.GameStop,
                GameEvtCode.GameStart,
                GameEvtCode.GamePuase,
            }, this);

            StartSocket();
        }

        void OnDestroy()
        {
            StopSocket();
        }

        public void Disconnect(ClientPer client, string reason)
        {

        }

        public override void Execute(int evtCode,params object[] msg)
        {
            switch (evtCode)
            {
                case GameEvtCode.GameDisconnect:
                    ChangeAndSendBroadMsg(evtCode);

                    StopClients();

                    break;

                case GameEvtCode.GameConnect:
                    ChangeAndSendBroadMsg(evtCode);
                    break;

                case GameEvtCode.GameStop:
                    if(broadMsg.Status == GameEvtCode.GameDisconnect)
                        break;
                    else
                    {
                        ChangeAndSendBroadMsg(GameEvtCode.GameConnect);
                    }
                    break;

                case GameEvtCode.GameStart:
                    ChangeAndSendBroadMsg(evtCode);
                    break;

                case GameEvtCode.GamePuase:
                    ChangeAndSendBroadMsg(evtCode);
                    break;

                case NetEvtCode.Client2TcpMsg:
                    ClientPer client = (ClientPer)msg[0];
                    SocketSendMsg client2tcpMsg = (SocketSendMsg)msg[1];
                    if (client2tcpMsg != null)
                        TCPSend(client, client2tcpMsg);

                    break;
                case NetEvtCode.Clients2TcpMsgs:

                    SocketSendMsg clients2tcpMsg = (SocketSendMsg)msg[0];
                    if (clients2tcpMsg != null)
                        TCPSend(clients2tcpMsg);
                    break;
            }
        }

        private void StartSocket()
        {
            server = new ServerPer();
            server.SetApplication(new NetRCenter());
            server.Start(Config.tcpPort, 1);

            broader = new BroadcastPer();
            broader.Start(string.Empty, 16666);
            StartCoroutine(IeBroad());
        }

        private void StopClients()
        {
            if (server != null)
                server.CloseClients();
        }

        private void StopSocket()
        {
            StopAllCoroutines();

            if (server != null)
                server.CloseSocket();
            
            if (broader != null)
                broader.CloseSocket();
        }

       private void TCPSend(ClientPer client,SocketSendMsg msg)
        {
            Debug.Log(client);
            if (client == null)
            {
                Debug.Log("发送消息的client为空");
                return;
            }

            msgRecord.Add(msg);
            client.Send(msg);
        }

       private void TCPSend(SocketSendMsg msg)
       {
           server.SendMsg(tcpClientSendMsg, msg);

       }

       void tcpClientSendMsg(ClientPer client, object msgPacket)
       {
           SocketSendMsg msg = null;
           if (msgPacket != null)
               msg = (SocketSendMsg) msgPacket;

           msgRecord.Add(msg);
           client.Send(msg);
       }


       static BroadMsg  broadMsg = new BroadMsg();
       /// <summary>
       /// 更新信息及发送
       /// </summary>
       /// <param name="stateCode"></param>
        private void ChangeAndSendBroadMsg(int stateCode = 0)
        {
            broadMsg.MT = 0;//指示报文类型
            broadMsg.DT = 1;//指示设备类型，1为TV
            broadMsg.IP = EncodeTool.GetLocalIp4();//设备IP
            broadMsg.Port = Config.tcpPort;//设备端口
            broadMsg.Max = Config.broadCount;//最大连接数
            broadMsg.Status = stateCode;//连接状态：0.未连接；1.已连接；2.游戏中；3.暂停中；4.错误
            broadMsg.ID =Config.gameID;//游戏ID，字符串类型
            broadMsg.Tag = EncodeTool.GetTimestamp(DateTime.Now);//广播序号
            broadMsg.Version = Config.protocolVersion;//协议版本号

#if DEBUG_MODEL
            Debug.Log(string.Format("广播状态已更新为 {0} 并发送", stateCode));
#endif
            UDPSend(broadMsg);
        }

        private IEnumerator IeBroad()
        {
            //init msg
            ChangeAndSendBroadMsg();

            float endPauseTime = 1f;

            float waitTime = 0.5f;
            while (true)
            {
                endPauseTime = Time.realtimeSinceStartup + waitTime;
                yield return new WaitWhile(() => Time.realtimeSinceStartup < endPauseTime);

                broadMsg.Tag  = EncodeTool.GetTimestamp(DateTime.Now);//更新
                UDPSend(broadMsg);
            }
        }

        private void UDPSend(BroadMsg broadMsg)
        {
            string json = string.Empty;
            try
            {
                json = JsonConvert.SerializeObject(broadMsg);
            }
            catch (Exception e)
            {
                Debug.LogError("BroadMsg 内容出错");
            }

            if (!string.IsNullOrEmpty(json))
                broader.SendMessageByBroadcast(json);
        }
    }
}
